package planner.plan;

import java.util.ArrayList;
import java.util.Iterator;

import planner.domain.Operator;


public class PlanStep {

	private final String owString = "ow:";
	private final String impString = "imp:";
	
	private Operator operator;
	
	private int level;
	
	private ArrayList<String> openPreConditions;
	private ArrayList<PlanStep> previousSteps;
	private ArrayList<PlanStep>	childSteps;
	
	private final boolean debug = false;
		
	public PlanStep(Operator op){
		this.operator = op;
		openPreConditions = (ArrayList<String>)op.getPreconditions().clone();
		previousSteps = new ArrayList<PlanStep>();
		childSteps =  new ArrayList<PlanStep>();
	}
	
	public PlanStep(String name, ArrayList<String> preConditions){
		operator = new Operator(name, preConditions);
		openPreConditions = (ArrayList<String>)operator.getPreconditions().clone();
		previousSteps = new ArrayList<PlanStep>();
		childSteps =  new ArrayList<PlanStep>();
	}
	
	public void clearSolvedConditions(){
		openPreConditions = (ArrayList<String>)operator.getPreconditions().clone();
	}
	
	public String getOperatorName(){
		return operator.getName();
	}
	
	public void addPreviousStep(PlanStep ps){
		
		openPreConditions.removeAll(ps.getOperatorEffects());
		previousSteps.add(ps);
		ps.addChildStep(this);
		ps.setLevel(level + 1);
		
		if(debug){
			System.out.println("Solving Conditions " + ps.getOperatorEffects() + " from Step " + operator.getName());
			System.out.println("Step still has this conditions to solve: " +openPreConditions);
		}
	}
	
	public void removePreviousStep(PlanStep ps){
		previousSteps.remove(ps);
	}
	
	public void addChildStep(PlanStep ps){
		childSteps.add(ps);
	}
	
	public ArrayList<PlanStep> getPreviousSteps(){
		return previousSteps;
	}
	
	public ArrayList<PlanStep> getChildSteps(){
		return childSteps;
	}
	

	public void removeChildSteps() {
		Iterator<PlanStep> iChilds = childSteps.iterator();
		
		while (iChilds.hasNext()) {
			PlanStep child = (PlanStep) iChilds.next();
			child.removePreviousStep(this);
		}
	
		childSteps.clear();
	}
	
	public boolean hasConditionSolvedBy(PlanStep s){
		Iterator<String> iEffect = s.getOperatorEffects().iterator();
		
		while (iEffect.hasNext()) {
			String effect = (String) iEffect.next();
			if(openPreConditions.contains(effect))
				return true;
		}
		return false;
	}
	
	public ArrayList<String> getOperatorEffects(){
		return operator.getEffects();
	}
	
	public boolean hasOpenPC (){		
		return !openPreConditions.isEmpty();
	}
	
	public void printPreviousStep(){
		Iterator<PlanStep> iPS = previousSteps.iterator();
		while (iPS.hasNext()) {
			PlanStep planStep = (PlanStep) iPS.next();
			System.out.print(planStep.getOperatorName() + " ");
		}
		System.out.println();
	}
	
	public boolean hasCondition(String condition){
			return openPreConditions.contains(condition);
		
	}
	
	public void removeFromOpenConditions(ArrayList<String> conditions){
		openPreConditions.removeAll(conditions);
	}
	
	public void removeFromOpenConditions(String conditions){
		openPreConditions.remove(conditions);
	}
	
	public void changePreConditions(String oldCondition, ArrayList<String> newConditions){
		openPreConditions.remove(oldCondition);
		openPreConditions.addAll(newConditions);		
	}
	
	public ArrayList<String> getOpenPreConditions(){
		return openPreConditions;
	}
	
	public int getLevel(){
		return level;
	}
	
	public void setLevel(int lvl){
		this.level = lvl;
	}
	
	public boolean isOverwriteOperator(){
		return (operator.getName().indexOf(owString) > -1);
	}
	
	public boolean isImplemetationOperator(){
		return (operator.getName().indexOf(impString) > -1);
	}
	
	public boolean isSpecialStep(){
		return (isOverwriteOperator() || isImplemetationOperator());
	}

	public ArrayList<String> getOperatorCondition(){
		return operator.getPreconditions();
	}
	
}
